home *** CD-ROM | disk | FTP | other *** search
/ Kit PC World De Ampliacion De Windows 95 / Kit PC World de ampliacion de Windows 95.iso / internet / sweeper / samples / docobj / site.cpp < prev    next >
C/C++ Source or Header  |  1995-11-22  |  9KB  |  442 lines

  1. /*
  2.  * SITE.CPP
  3.  * Document Object Site Object
  4.  *
  5.  * Copyright (c)1995 Microsoft Corporation, All Rights Reserved
  6.  * Kraig Brockschmidt, kraigb@microsoft.com
  7.  */
  8.  
  9.  
  10. #include "framer.h"
  11.  
  12.  
  13. /*
  14.  * CSite::CSite
  15.  * CSite::~CSite
  16.  *
  17.  * Constructor Parameters:
  18.  *  dwID            DWORD identifer for this site.
  19.  *  hWnd            HWND of the window associated with the site
  20.  *  pFR             PCFrame to the parent structure.
  21.  */
  22.  
  23. CSite::CSite(DWORD dwID, HWND hWnd, PCFrame pFR)
  24.     {
  25.     m_cRef=0;
  26.     m_dwID=dwID;
  27.     m_hWnd=hWnd;
  28.     m_pFR=pFR;
  29.  
  30.     m_fInitialized=0;
  31.     m_pIStorage=NULL;
  32.  
  33.     m_pObj=NULL;
  34.     
  35.     m_pIOleObject=NULL;
  36.     m_pIOleIPObject=NULL;
  37.     m_pIOleDocView=NULL;
  38.  
  39.     m_pImpIOleClientSite=NULL;
  40.     m_pImpIAdviseSink=NULL;
  41.     m_pImpIOleIPSite=NULL;
  42.     m_pImpIOleDocumentSite=NULL;
  43.  
  44.     m_fDocObj=FALSE;
  45.     return;
  46.     }
  47.  
  48.  
  49. CSite::~CSite(void)
  50.     {
  51.     //Object pointers cleaned up in Close.
  52.  
  53.     //We delete our own interfaces since we control them
  54.     DeleteInterfaceImp(m_pImpIOleDocumentSite);
  55.     DeleteInterfaceImp(m_pImpIOleIPSite);
  56.     DeleteInterfaceImp(m_pImpIAdviseSink);
  57.     DeleteInterfaceImp(m_pImpIOleClientSite);
  58.     return;
  59.     }
  60.  
  61.  
  62.  
  63.  
  64. /*
  65.  * CSite::QueryInterface
  66.  * CSite::AddRef
  67.  * CSite::Release
  68.  *
  69.  * Purpose:
  70.  *  IUnknown members for CSite object.
  71.  */
  72.  
  73. STDMETHODIMP CSite::QueryInterface(REFIID riid, void **ppv)
  74.     {
  75.     *ppv=NULL;
  76.  
  77.     if (IID_IUnknown==riid)
  78.         *ppv=this;
  79.  
  80.     if (IID_IOleClientSite==riid)
  81.         *ppv=m_pImpIOleClientSite;
  82.  
  83.     if (IID_IAdviseSink==riid)
  84.         *ppv=m_pImpIAdviseSink;
  85.  
  86.     if (IID_IOleWindow==riid || IID_IOleInPlaceSite==riid)
  87.         *ppv=m_pImpIOleIPSite;
  88.  
  89.     if (IID_IOleDocumentSite==riid)
  90.         *ppv=m_pImpIOleDocumentSite;
  91.  
  92.     if (NULL!=*ppv)
  93.         {
  94.         ((LPUNKNOWN)*ppv)->AddRef();
  95.         return NOERROR;
  96.         }
  97.  
  98.     return ResultFromScode(E_NOINTERFACE);
  99.     }
  100.  
  101.  
  102. STDMETHODIMP_(ULONG) CSite::AddRef(void)
  103.     {
  104.     return ++m_cRef;
  105.     }
  106.  
  107. STDMETHODIMP_(ULONG) CSite::Release(void)
  108.     {
  109.     if (0!=--m_cRef)
  110.         return m_cRef;
  111.  
  112.     delete this;
  113.     return 0;
  114.     }
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121. /*
  122.  * CSite::Create
  123.  *
  124.  * Purpose:
  125.  *  Asks the site to instantiate an object given a filename.
  126.  *  This goes through OleCreateFromFile and will either create
  127.  *  an embedded object or a package (embedded) object.  When
  128.  *  activated, this will either launch the app and activate
  129.  *  as a DocObject, launch the app and open the file, or fail
  130.  *  because no app can open the file.
  131.  *
  132.  * Parameters:
  133.  *  pszFile         LPTSTR of the file from which to create the object.
  134.  *  pIStorage       IStorage * of the parent storage in which we're
  135.  *                  to create an IStorage for the new object.
  136.  *  dwID            DWORD identifier for this site.
  137.  *
  138.  * Return Value:
  139.  *  BOOL            Result of the creation.
  140.  */
  141.  
  142. BOOL CSite::Create(LPTSTR pszFile, IStorage *pIStorage)
  143.     {
  144.     HRESULT             hr=E_FAIL;
  145.     LPUNKNOWN           pObj;
  146.  
  147.     //Create a new storage for this object (sets m_pIStorage)
  148.     if (!CreateStorage(pIStorage))
  149.         return FALSE;
  150.  
  151.     //Now create an object from the file
  152.     hr=OleCreateFromFile(CLSID_NULL, pszFile, IID_IUnknown
  153.         , OLERENDER_NONE, NULL, NULL, m_pIStorage, (void **)&pObj);
  154.  
  155.  
  156.     //If creation didn't work, get rid of the element Open created.
  157.     if (FAILED(hr))
  158.         {
  159.         Destroy(pIStorage);
  160.         return FALSE;
  161.         }
  162.  
  163.     //We don't get the size if PatronObject data was seen already.
  164.     if (!ObjectInitialize(pObj))
  165.         {
  166.         Destroy(pIStorage);
  167.         return FALSE;
  168.         }
  169.  
  170.     m_fInitialized=TRUE;
  171.     return TRUE;
  172.     }
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179. /*
  180.  * CSite::ObjectInitialize
  181.  * (Protected)
  182.  *
  183.  * Purpose:
  184.  *  Performs operations necessary after creating an object or
  185.  *  reloading one from storage.
  186.  *
  187.  * Parameters:
  188.  *  pObj            LPUNKNOWN of the object in this tenant.
  189.  *  pFE             LPFORMATETC describing the graphic here.
  190.  *  dwData          DWORD extra data.  If pFE->dwAspect==
  191.  *                  DVASPECT_ICON then this is the iconic metafile.
  192.  *
  193.  * Return Value:
  194.  *  BOOL            TRUE if the function succeeded, FALSE otherwise.
  195.  */
  196.  
  197. BOOL CSite::ObjectInitialize(LPUNKNOWN pObj)
  198.     {
  199.     HRESULT         hr;
  200.     DWORD           dw;
  201.  
  202.     if (NULL==pObj)
  203.         return FALSE;
  204.  
  205.     m_pObj=pObj;
  206.  
  207.     //We need an IOleObject most of the time, so get one here.
  208.     m_pIOleObject=NULL;
  209.     hr=pObj->QueryInterface(IID_IOleObject, (void **)&m_pIOleObject);         
  210.  
  211.     /*
  212.      * Follow up object creation with advises and so forth.  If
  213.      * we cannot get IOleObject here, then we know we can't do
  214.      * any IOleObject actions from here on--object is static.
  215.      */
  216.     if (FAILED(hr))
  217.         return TRUE;
  218.  
  219.     //SetClientSite is critical for DocObjects
  220.     m_pIOleObject->SetClientSite(m_pImpIOleClientSite);
  221.     m_pIOleObject->Advise(m_pImpIAdviseSink, &dw);
  222.  
  223.     return TRUE;
  224.     }
  225.  
  226.  
  227.  
  228.  
  229. /*
  230.  * CSite::CreateStorage
  231.  *
  232.  * Purpose:
  233.  *  Creates an sub-storage within a given parent storage,
  234.  *  setting m_pIStorage.
  235.  *
  236.  * Parameters:
  237.  *  pIStorage       IStorage * of the parent storage
  238.  *
  239.  * Return Value:
  240.  *  BOOL            TRUE if creation succeeds, FALSE otherwise.
  241.  */
  242.  
  243. BOOL CSite::CreateStorage(IStorage *pIStorage)
  244.     {
  245.     HRESULT     hr;
  246.     DWORD       dwMode=STGM_TRANSACTED | STGM_READWRITE
  247.                     | STGM_SHARE_EXCLUSIVE;
  248.     WCHAR       szName[32];
  249.  
  250.     if (NULL==pIStorage)
  251.         return FALSE;
  252.  
  253.     /*
  254.      * Attempt to open the storage under this ID.  If there is
  255.      * none, then create it.  In either case we end up with an
  256.      * IStorage that we either save in pPage or release.
  257.      */
  258.     wsprintf(szName, TEXT("Site %lu"), m_dwID);
  259.  
  260.     hr=pIStorage->CreateStorage(szName, dwMode, 0, 0, &m_pIStorage);
  261.  
  262.     if (FAILED(hr))
  263.         return FALSE;
  264.  
  265.     //Create interface implementations
  266.     m_pImpIOleClientSite=new CImpIOleClientSite(this, this);
  267.     m_pImpIAdviseSink=new CImpIAdviseSink(this, this);
  268.     m_pImpIOleIPSite=new CImpIOleInPlaceSite(this, this);
  269.     m_pImpIOleDocumentSite=new CImpIOleDocumentSite(this, this);
  270.  
  271.     if (NULL==m_pImpIOleClientSite || NULL==m_pImpIAdviseSink
  272.         || NULL==m_pImpIOleIPSite || NULL==m_pImpIOleDocumentSite)
  273.         return FALSE;
  274.  
  275.     return TRUE;
  276.     }
  277.  
  278.  
  279.  
  280.  
  281. /*
  282.  * CSite::Close
  283.  *
  284.  * Purpose:
  285.  *  Possibly commits the storage, then releases it, afterwards
  286.  *  frees alls the object pointers.
  287.  *
  288.  * Parameters:
  289.  *  fCommit         BOOL indicating if we're to commit.
  290.  *
  291.  * Return Value:
  292.  *  None
  293.  */
  294.  
  295. void CSite::Close(BOOL fCommit)
  296.     {
  297.     //OnInPlaceDeactivate releases this pointer.
  298.     if (NULL!=m_pIOleIPObject)
  299.         m_pIOleIPObject->InPlaceDeactivate();
  300.  
  301.     ReleaseInterface(m_pIOleDocView);
  302.  
  303.     if (NULL!=m_pIOleObject)
  304.         {
  305.         m_pIOleObject->Close(fCommit
  306.             ? OLECLOSE_SAVEIFDIRTY : OLECLOSE_NOSAVE);
  307.         ReleaseInterface(m_pIOleObject);
  308.         }
  309.  
  310.     ReleaseInterface(m_pObj);
  311.     ReleaseInterface(m_pIStorage);
  312.  
  313.     return;
  314.     }
  315.  
  316.  
  317.  
  318.  
  319. /*
  320.  * CSite::Update
  321.  *
  322.  * Purpose:
  323.  *  Forces a commit on the object's storage
  324.  *
  325.  * Parameters:
  326.  *  None
  327.  *
  328.  * Return Value:
  329.  *  None
  330.  */
  331.  
  332. void CSite::Update(void)
  333.     {
  334.     LPPERSISTSTORAGE    pIPS;
  335.  
  336.     if (NULL!=m_pIStorage)
  337.         return;
  338.  
  339.     m_pObj->QueryInterface(IID_IPersistStorage, (void **)&pIPS);
  340.     OleSave(pIPS, m_pIStorage, TRUE);
  341.     pIPS->SaveCompleted(NULL);
  342.     pIPS->Release();
  343.  
  344.     m_pIStorage->Commit(STGC_DEFAULT);
  345.     return;
  346.     }
  347.  
  348.  
  349.  
  350.  
  351.  
  352. /*
  353.  * CSite::Destroy
  354.  *
  355.  * Purpose:
  356.  *  Removes this storage from the parent storage.  The caller should
  357.  *  eventually delete this CSite object to free the object herein.
  358.  *  Nothing is committed when being destroyed.
  359.  *
  360.  * Parameters:
  361.  *  pIStorage       IStorage * of the parent
  362.  *
  363.  * Return Value:
  364.  *  None
  365.  */
  366.  
  367. void CSite::Destroy(IStorage *pIStorage)
  368.     {
  369.     OLECHAR     szName[32];
  370.  
  371.     if (NULL==pIStorage)
  372.         return;
  373.  
  374.     if (NULL!=m_pObj)
  375.         Close(FALSE);
  376.     
  377.     wsprintf(szName, TEXT("Site %lu"), m_dwID);
  378.     pIStorage->DestroyElement(szName);
  379.     return;
  380.     }
  381.  
  382.  
  383.  
  384.  
  385.  
  386. /*
  387.  * CSite::Activate
  388.  *
  389.  * Purpose:
  390.  *  Activates a verb on the object living in the site.
  391.  *
  392.  * Parameters:
  393.  *  iVerb           LONG of the verb to execute.
  394.  *
  395.  * Return Value:
  396.  *  None
  397.  */
  398.  
  399. void CSite::Activate(LONG iVerb)
  400.     {
  401.     CHourglass *pHour;
  402.     RECT        rc;
  403.             
  404.     pHour=new CHourglass;
  405.  
  406.     GetClientRect(m_hWnd, &rc);
  407.     m_pIOleObject->DoVerb(iVerb, NULL, m_pImpIOleClientSite, 0
  408.         , m_hWnd, &rc);
  409.  
  410.     delete pHour;
  411.     return;
  412.     }
  413.  
  414.  
  415.  
  416.  
  417. /*
  418.  * CSite::UpdateObjectRects
  419.  *
  420.  * Purpose:
  421.  *  Informs the site that the client area window was resized and
  422.  *  that the site needs to also tell the DocObject of the resize.
  423.  *
  424.  * Parameters:
  425.  *  None
  426.  *
  427.  * Return Value:
  428.  *  None
  429.  */
  430.  
  431. void CSite::UpdateObjectRects(void)
  432.     {
  433.     RECT    rc;
  434.  
  435.     if (NULL==m_pIOleDocView)
  436.         return;
  437.  
  438.     GetClientRect(m_hWnd, &rc);
  439.     m_pIOleDocView->SetRect(&rc);
  440.     return;
  441.     }
  442.